package com.yisoo.rs.rsmovie.service.impl;

import com.yisoo.rs.common.vo.MovieJsonVo;
import com.yisoo.rs.rsmovie.entity.*;
import com.yisoo.rs.rsmovie.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Function;
import java.util.stream.Collectors;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yisoo.rs.common.utils.PageUtils;
import com.yisoo.rs.common.utils.Query;

import com.yisoo.rs.rsmovie.dao.MoviesDao;


@Service("moviesService")
public class MoviesServiceImpl extends ServiceImpl<MoviesDao, MoviesEntity> implements MoviesService {

    @Autowired
    StarService starService;
    @Autowired
    DirectorService directorService;
    @Autowired
    WriterService writerService;
    @Autowired
    TypeService typeService;

    @Autowired
    MvRelDrtService mvRelDrtService;
    @Autowired
    MvRelStarService mvRelStarService;
    @Autowired
    MvRelTypeService mvRelTypeService;
    @Autowired
    MvRelWrtService mvRelWrtService;
    @Autowired
    ThreadPoolExecutor executor;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MoviesEntity> page = this.page(
                new Query<MoviesEntity>().getPage(params),
                new QueryWrapper<MoviesEntity>()
        );

        return new PageUtils(page);
    }
    @Override
    public boolean quickImport(Long appId, List<MovieJsonVo> dataList) {
        System.out.println("开始");
//        待插入的电影列表
        List<MoviesEntity> moviesEntities = MoviesEntity.generatorByMovieJsonVo(appId, dataList);
        Map<String,MoviesEntity> moviesReIndex;
////        待插入的演员列表
        List<StarEntity>  starEntities= StarEntity.generatorByMovieJsonVo(appId,dataList);
        Map<String,StarEntity> starReIndex;
//        待插入的编剧
        List<WriterEntity> writerEntities = WriterEntity.generatorByMovieJsonVo(appId,dataList);
        Map<String,WriterEntity> writerReIndex;

//        待插入的导演
        List<DirectorEntity> directorEntities = DirectorEntity.generatorByMovieJsonVo(appId,dataList);
        Map<String,DirectorEntity> directorReIndex;
//        待插入的类型
        List<TypeEntity> typeEntities = TypeEntity.generatorByMovieJsonVo(appId,dataList);
        Map<String, TypeEntity> typeReIndex;

        System.out.println("数据解析完成");

        CompletableFuture<Void> MoviesFuture = CompletableFuture.runAsync(() -> {
            this.saveBatch(moviesEntities);
            System.out.println("moviesService");
        }, executor);
        CompletableFuture<Void> TypeFuture = CompletableFuture.runAsync(() ->{
            typeService.saveBatch(typeEntities);
            System.out.println("typeService");
        }, executor);
        CompletableFuture<Void> DirectorFuture = CompletableFuture.runAsync(() ->{
            directorService.saveBatch(directorEntities);
            System.out.println("directorService");

        }, executor);
        CompletableFuture<Void> StarFuture = CompletableFuture.runAsync(() ->{
            starService.saveBatch(starEntities);
            System.out.println("starService");
        }, executor);
        CompletableFuture<Void>WriterFuture = CompletableFuture.runAsync(() ->{
            writerService.saveBatch(writerEntities);
            System.out.println("writerService");
        }, executor);
        try {
            CompletableFuture.allOf(MoviesFuture,TypeFuture,DirectorFuture,StarFuture,WriterFuture).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("实体数据存入完成");
        moviesReIndex = moviesEntities.stream().collect(Collectors.toMap(MoviesEntity::getMvName, Function.identity()));
        typeReIndex = typeEntities.stream().collect(Collectors.toMap(TypeEntity::getTypeName, Function.identity()));
        directorReIndex = directorEntities.stream().collect(Collectors.toMap(DirectorEntity::getDirectorName, Function.identity()));
        starReIndex = starEntities.stream().collect(Collectors.toMap(StarEntity::getStarName, Function.identity()));
        writerReIndex = writerEntities.stream().collect(Collectors.toMap(WriterEntity::getWriterName, Function.identity()));
        System.out.println("准备映射map");
//        //      刷新关系
        CompletableFuture<Void> SaveOrUpdateToTypeFuture = CompletableFuture.runAsync(() ->{
            SaveOrUpdateToType(dataList,typeReIndex,moviesReIndex);
            System.out.println("SaveOrUpdateToType");
        }, executor);
        CompletableFuture<Void> SaveOrUpdateToStarFuture = CompletableFuture.runAsync(() ->{
            SaveOrUpdateToStar(dataList,starReIndex,moviesReIndex);
            System.out.println("SaveOrUpdateToStar");
        }, executor);
        CompletableFuture<Void> SaveOrUpdateToDirectorFuture = CompletableFuture.runAsync(() ->{
            SaveOrUpdateToDirector(dataList,directorReIndex,moviesReIndex);
            System.out.println("SaveOrUpdateToDirector");
        }, executor);
        CompletableFuture<Void> SaveOrUpdateToWriterFuture = CompletableFuture.runAsync(() ->{
            SaveOrUpdateToWriter(dataList,writerReIndex,moviesReIndex);
            System.out.println("SaveOrUpdateToWriter");
        }, executor);
        try {
            CompletableFuture.allOf(SaveOrUpdateToTypeFuture,SaveOrUpdateToStarFuture,SaveOrUpdateToDirectorFuture,SaveOrUpdateToWriterFuture).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        return true;
    }


    private void SaveOrUpdateToWriter(List<MovieJsonVo> dataList, Map<String, WriterEntity> writerReIndex,Map<String, MoviesEntity> moviesReIndex) {
        ArrayList<MvRelWrtEntity> arrayList = new ArrayList<>();
        for (MovieJsonVo m:dataList) {
            MoviesEntity entity = moviesReIndex.get(m.getMvName());
            List<String> list = m.getMvWriter();
            for (String key:list){
                arrayList.add(new MvRelWrtEntity(null, entity.getMvId(), writerReIndex.get(key).getWriterId(),entity.getAppId()));
            }
        }
        mvRelWrtService.saveBatch(arrayList);
    }

    private void SaveOrUpdateToDirector(List<MovieJsonVo> dataList, Map<String, DirectorEntity> directorReIndex,Map<String, MoviesEntity> moviesReIndex) {
        ArrayList<MvRelDrtEntity> arrayList = new ArrayList<>();
        for (MovieJsonVo m:dataList) {
            MoviesEntity entity = moviesReIndex.get(m.getMvName());
            List<String> list = m.getMvDirector();
            for (String key:list){
                arrayList.add(new MvRelDrtEntity(null, entity.getMvId(), directorReIndex.get(key).getDirectorId(),entity.getAppId()));
            }
        }
        mvRelDrtService.saveBatch(arrayList);
    }

    private void SaveOrUpdateToStar(List<MovieJsonVo> dataList, Map<String, StarEntity> starReIndex,  Map<String, MoviesEntity> moviesReIndex) {
        ArrayList<MvRelStarEntity> arrayList = new ArrayList<>();
        for (MovieJsonVo m:dataList) {
            MoviesEntity entity = moviesReIndex.get(m.getMvName());
            List<String> list = m.getMvStar();
            for (String key:list){
                arrayList.add(new MvRelStarEntity(null, entity.getMvId(), starReIndex.get(key).getStarId(),entity.getAppId()));
            }
        }
        mvRelStarService.saveBatch(arrayList);
    }

    private void SaveOrUpdateToType(List<MovieJsonVo> dataList, Map<String, TypeEntity> typeReIndex,  Map<String, MoviesEntity> moviesReIndex) {
        ArrayList<MvRelTypeEntity> arrayList = new ArrayList<>();
        for (MovieJsonVo m:dataList) {
            MoviesEntity entity = moviesReIndex.get(m.getMvName());
            List<String> list = m.getMvType();
            for (String key:list){
                arrayList.add(new MvRelTypeEntity(null, entity.getMvId(), typeReIndex.get(key).getTypeId(),entity.getAppId()));
            }
        }
        mvRelTypeService.saveBatch(arrayList);
    }

//    2021年12月8日22:44:15 bak
//    public boolean quickImport_bak(Long appId, List<MovieJsonVo> dataList) {
////        待插入的电影列表
//        Map<String,Integer> moviesReIndex = new HashMap<>();
//        List<MoviesEntity> moviesEntities = MoviesEntity.generatorByMovieJsonVo(appId, dataList,moviesReIndex);
////        待插入的演员列表
//        Map<String,Integer> starReIndex = new HashMap<>();
//        List<StarEntity> starEntities = StarEntity.generatorByMovieJsonVo(dataList,starReIndex);
////        待插入的编剧
//        Map<String,Integer> writerReIndex = new HashMap<>();
//        List<WriterEntity> writerEntities = WriterEntity.generatorByMovieJsonVo(dataList,writerReIndex);
////        待插入的导演
//        Map<String,Integer> directorReIndex = new HashMap<>();
//        List<DirectorEntity> directorEntities = DirectorEntity.generatorByMovieJsonVo(dataList,directorReIndex);
////        待插入的类型
//        Map<String,Integer> typeReIndex = new HashMap<>();
//        List<TypeEntity> typeEntities = TypeEntity.generatorByMovieJsonVo(dataList,typeReIndex);
//
//        CompletableFuture<Void> MoviesFuture = CompletableFuture.runAsync(() -> {
//            List<MoviesEntity> sourceMoviesList = this.list();
//            for (MoviesEntity temp:sourceMoviesList){
//                if (moviesReIndex.containsKey(temp.getMvName())){
//                    Integer index = moviesReIndex.get(temp.getMvName());
//                    MoviesEntity entity = moviesEntities.get(index);
//                    entity.setMvId(temp.getMvId());
//                    moviesEntities.set(index,entity);
//                }
//            }
//            this.saveOrUpdateBatch(moviesEntities);
//        }, executor);
//        CompletableFuture<Void> TypeFuture = CompletableFuture.runAsync(() ->{
//            List<TypeEntity> sourceTypeList = typeService.list();
//            for (TypeEntity temp:sourceTypeList){
//                if (typeReIndex.containsKey(temp.getTypeName())){
//                    Integer index = typeReIndex.get(temp.getTypeName());
//                    TypeEntity entity = typeEntities.get(index);
//                    entity.setTypeId(temp.getTypeId());
//                    typeEntities.set(index,entity);
//                }
//            }
//            typeService.saveOrUpdateBatch(typeEntities);
//        }, executor);
//        CompletableFuture<Void> DirectorFuture = CompletableFuture.runAsync(() ->{
//            List<DirectorEntity> sourceDirectorList = directorService.list();
//            for (DirectorEntity temp:sourceDirectorList){
//                if (directorReIndex.containsKey(temp.getDirectorName())){
//                    Integer index = directorReIndex.get(temp.getDirectorName());
//                    DirectorEntity entity = directorEntities.get(index);
//                    entity.setDirectorId(temp.getDirectorId());
//                    directorEntities.set(index,entity);
//                }
//            }
//            directorService.saveOrUpdateBatch(directorEntities);
//        }, executor);
//        CompletableFuture<Void> StarFuture = CompletableFuture.runAsync(() ->{
//            List<StarEntity> sourceStarList = starService.list();
//            for (StarEntity temp:sourceStarList){
//                if (starReIndex.containsKey(temp.getStarName())){
//                    Integer index = starReIndex.get(temp.getStarName());
//                    StarEntity entity = starEntities.get(index);
//                    entity.setStarId(temp.getStarId());
//                    starEntities.set(index,entity);
//                }
//            }
//            starService.saveOrUpdateBatch(starEntities);
//        }, executor);
//        CompletableFuture<Void>WriterFuture = CompletableFuture.runAsync(() ->{
//            List<WriterEntity> sourceWriterList = writerService.list();
//            for (WriterEntity temp:sourceWriterList){
//                if (writerReIndex.containsKey(temp.getWriterName())){
//                    Integer index = writerReIndex.get(temp.getWriterName());
//                    WriterEntity entity = writerEntities.get(index);
//                    entity.setWriterId(temp.getWriterId());
//                    writerEntities.set(index,entity);
//                }
//            }
//            writerService.saveOrUpdateBatch(writerEntities);
//        }, executor);
//        try {
//            CompletableFuture.allOf(MoviesFuture,TypeFuture,DirectorFuture,StarFuture,WriterFuture).get();
//        } catch (InterruptedException | ExecutionException e) {
//            e.printStackTrace();
//        }
        //      刷新关系
//        CompletableFuture<Void> SaveOrUpdateToTypeFuture = CompletableFuture.runAsync(() ->{
//            SaveOrUpdateToType(dataList,typeReIndex,typeEntities,moviesReIndex,moviesEntities);
//
//        }, executor);
//        CompletableFuture<Void> SaveOrUpdateToStarFuture = CompletableFuture.runAsync(() ->{
//            SaveOrUpdateToStar(dataList,starReIndex,starEntities,moviesReIndex,moviesEntities);
//
//        }, executor);
//        CompletableFuture<Void> SaveOrUpdateToDirectorFuture = CompletableFuture.runAsync(() ->{
//            SaveOrUpdateToDirector(dataList,directorReIndex,directorEntities,moviesReIndex,moviesEntities);
//
//        }, executor);
//        CompletableFuture<Void> SaveOrUpdateToWriterFuture = CompletableFuture.runAsync(() ->{
//            SaveOrUpdateToWriter(dataList,writerReIndex,writerEntities,moviesReIndex,moviesEntities);
//
//        }, executor);
//        try {
//            CompletableFuture.allOf(SaveOrUpdateToTypeFuture,SaveOrUpdateToStarFuture,SaveOrUpdateToDirectorFuture,SaveOrUpdateToWriterFuture).get();
//        } catch (InterruptedException | ExecutionException e) {
//            e.printStackTrace();
//        }
//        return true;
//    }

//    private void SaveOrUpdateToWriter_bak(List<MovieJsonVo> dataList, Map<String, Integer> writerReIndex, List<WriterEntity> writerEntities, Map<String, Integer> moviesReIndex, List<MoviesEntity> moviesEntities) {
//        QueryWrapper<MvRelWrtEntity> queryWrapper = null;
//        for (MovieJsonVo m:dataList) {
//            String mvName = m.getMvName();
//            List<String> list = m.getMvWriter();
//            for (String key:list){
//                Long mvId = moviesEntities.get(moviesReIndex.get(mvName)).getMvId();
//                Long Id = writerEntities.get(writerReIndex.get(key)).getWriterId();
//                queryWrapper = new QueryWrapper<MvRelWrtEntity>().eq("mv_id",mvId).eq("writer_id",Id);
//                MvRelWrtEntity one = mvRelWrtService.getOne(queryWrapper);
//                if (one == null){
//                    one = new MvRelWrtEntity(null,mvId,Id);
//                    mvRelWrtService.saveOrUpdate(one);
//                }
//            }
//        }
//    }
//
//    private void SaveOrUpdateToDirector_bak(List<MovieJsonVo> dataList, Map<String, Integer> directorReIndex, List<DirectorEntity> directorEntities, Map<String, Integer> moviesReIndex, List<MoviesEntity> moviesEntities) {
//        QueryWrapper<MvRelDrtEntity> queryWrapper = null;
//        for (MovieJsonVo m:dataList) {
//            String mvName = m.getMvName();
//            List<String> list = m.getMvDirector();
//            for (String key:list){
//                Long mvId = moviesEntities.get(moviesReIndex.get(mvName)).getMvId();
//                Long Id = directorEntities.get(directorReIndex.get(key)).getDirectorId();
//                queryWrapper = new QueryWrapper<MvRelDrtEntity>().eq("mv_id",mvId).eq("director_id",Id);
//                MvRelDrtEntity one = mvRelDrtService.getOne(queryWrapper);
//                if (one == null){
//                    one = new MvRelDrtEntity(null,mvId,Id);
//                    mvRelDrtService.saveOrUpdate(one);
//                }
//            }
//        }
//    }
//
//    private void SaveOrUpdateToStar_bak(List<MovieJsonVo> dataList, Map<String, Integer> starReIndex, List<StarEntity> starEntities, Map<String, Integer> moviesReIndex, List<MoviesEntity> moviesEntities) {
//        QueryWrapper<MvRelStarEntity> queryWrapper = null;
//        for (MovieJsonVo m:dataList) {
//            String mvName = m.getMvName();
//            List<String> list = m.getMvStar();
//            for (String key:list){
//                Long mvId = moviesEntities.get(moviesReIndex.get(mvName)).getMvId();
//                Long Id = starEntities.get(starReIndex.get(key)).getStarId();
//                queryWrapper = new QueryWrapper<MvRelStarEntity>().eq("mv_id",mvId).eq("star_id",Id);
//                MvRelStarEntity one = mvRelStarService.getOne(queryWrapper);
//                if (one == null){
//                    one = new MvRelStarEntity(null,mvId,Id);
//                    mvRelStarService.saveOrUpdate(one);
//                }
//            }
//        }
//    }
//
//    private void SaveOrUpdateToType_bak(List<MovieJsonVo> dataList, Map<String, Integer> typeReIndex, List<TypeEntity> typeEntities, Map<String, Integer> moviesReIndex, List<MoviesEntity> moviesEntities) {
//        QueryWrapper<MvRelTypeEntity> queryWrapper = null;
//        for (MovieJsonVo m:dataList) {
//            String mvName = m.getMvName();
//            List<String> list = m.getMvType();
//            for (String key:list){
//                Long mvId = moviesEntities.get(moviesReIndex.get(mvName)).getMvId();
//                Long typeId = typeEntities.get(typeReIndex.get(key)).getTypeId();
//                queryWrapper = new QueryWrapper<MvRelTypeEntity>().eq("mv_id",mvId).eq("type_id",typeId);
//                MvRelTypeEntity one = mvRelTypeService.getOne(queryWrapper);
//                if (one == null){
//                    one = new MvRelTypeEntity(null,mvId,typeId);
//                    mvRelTypeService.saveOrUpdate(one);
//                }
//            }
//
//        }
//    }

}